/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_TIMESTAMP.c                                    */
/*  NOTE      =                                                    */
/*  DATE      = 2014/11/13 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <netinet/in.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frlog.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_util.h"

/*******************************************************************************
*  FUNC     :  解析时间类型，参照9i的oracle.sql.TIMESTAMP的public static Timestamp toTimestamp(byte[] paramArrayOfByte)方法
*  ARGS     :  *p_payload                           (数据内容)
*           :  ui_payload_len                       (数据长度)
*           :  *p_ll_out                            (1970年开始的一个微秒时间)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_TIMESTAMP_toLongLong(char *p_payload
                            , unsigned int ui_payload_len
                            , char **pp_out)
{
    int i_year = 0;
    int i_month = 0;
    int i_date = 0;
    int i_hour = 0;
    int i_minute = 0;
    int i_second = 0;
    int i_microsecond = 0;
    char *p_time_fmt_buf = NULL;
    char *p_time_buf = NULL;
    struct tm t;

    if (ui_payload_len < 7)
        goto error;

    i_year = (((int) p_payload[0]) - 100) * 100 + (((int) p_payload[1]) - 100);
    i_month = ((int) p_payload[2]) - 1;
    i_date = (int) p_payload[3];
    i_hour = ((int) p_payload[4]) - 1;
    i_minute = ((int) p_payload[5]) - 1;
    i_second = ((int) p_payload[6]) - 1;

    if (ui_payload_len == 11)
    {
        i_microsecond = ((int) p_payload[7]) << 24;
        i_microsecond |= ((int) p_payload[8]) << 16;
        i_microsecond |= ((int) p_payload[9]) << 8;
        i_microsecond |= ((int) p_payload[10]) & 255;
        i_microsecond /= 1000;
    }

    t.tm_year = i_year - 1900;
    t.tm_mon = i_month;
    t.tm_mday = i_date;
    t.tm_hour = i_hour;
    t.tm_min = i_minute;
    t.tm_sec = i_second;
    t.tm_isdst = -1;        // Is DST on? 1 = yes, 0 = no, -1 = unknown

    if ((p_time_fmt_buf = (char *) frmalloc(64 * sizeof(char))) == NULL)
    {
        ORA_PRINT_EMERG("can not malloc memory\n");
        ORA_FRLOG_ERROR("can not malloc memory");
        goto error;
    }
    memset(p_time_fmt_buf, 0x0, sizeof(char) * 64);

    if ((p_time_buf = (char *) frmalloc(64 * sizeof(char))) == NULL)
    {
        ORA_PRINT_EMERG("can not malloc memory\n");
        ORA_FRLOG_ERROR("can not malloc memory");
        goto error;
    }
    memset(p_time_buf, 0x0, sizeof(char) * 64);

//    strftime(p_time_fmt_buf, sizeof(char) * 64, "%Y-%m-%d %H:%M:%S.%%06u %z", &t);
    strftime(p_time_fmt_buf, sizeof(char) * 64, "%Y-%m-%dT%H:%M:%S.%%06uZ", &t);
    snprintf(p_time_buf, sizeof(char) * 64, p_time_fmt_buf, i_microsecond);

    *pp_out = p_time_buf;

    ora_free((void **) &p_time_fmt_buf);
    return FR_SUCC;
error:
    ora_free((void **) &p_time_fmt_buf);
    ora_free((void **) &p_time_buf);
    return FR_FAIL;
}
